Skip to content

fix: keep closed navbar panels out of the tab order - #782

Open
Henglie wants to merge 1 commit into
saicaca:mainfrom
Henglie:fix/closed-float-panel-focus-order
Open

Henglie wants to merge 1 commit into
saicaca:mainfrom
Henglie:fix/closed-float-panel-focus-order

Conversation

@Henglie

@Henglie Henglie commented Oct 25, 2026

Copy link
Copy Markdown

Closes #777.

Problem

Closed navbar float panels are only faded out (.float-panel-closed → opacity: 0; pointer-events: none), so their links, buttons and inputs keep the default tabIndex of 0 and stay in the sequential focus order. Tabbing past the light/dark switch walks through the controls of four panels that were never opened.

Solution

Add inert to a panel while it carries float-panel-closed. inert removes the whole subtree from focus, hit-testing and the accessibility tree without touching display or visibility, so the open/close transition keeps running and the existing click-outside handlers are unaffected.

  • src/components/widget/NavMenuPanel.astro, src/components/widget/DisplaySettings.svelte, src/components/LightDarkSwitch.svelte, src/components/Search.svelte — set the attribute in markup so it is correct on the first server-rendered frame.
  • src/layouts/Layout.astro — syncFloatPanelInert() mirrors the attribute from the closed class, plus a MutationObserver (class-only filter) for the three panels that mount via client:only and for the four places that toggle the class.

The closed class stays the single source of truth, so the open/close state machine is unchanged; there is no fifth panel (grep float-panel src/ matches only these four).

Validation

  • pnpm build succeeds: 8 pages built, Pagefind indexed 6 pages.
  • dist/index.html → <div id="nav-menu-panel" class="float-panel float-panel-closed …" inert>.
  • Real Chromium (Playwright 1.61 against astro preview): all four panels closed → inert=true, opacity=0; Tab visits 22 stops on desktop and 18 on mobile with none inside a panel. Opened → inert=false, opacity still animates and the controls are focusable; click-outside / mouseleave restore inert.
  • pnpm check reports 2 errors that are identical on the base commit (Navbar.astro, archive.astro), and Biome reports 5 pre-existing formatter diagnostics on these files; the added lines are unchanged from baseline formatting.

@vercel

vercel Bot commented Oct 25, 2026

Copy link
Copy Markdown

@Henglie is attempting to deploy a commit to the zephyirdgmailcom's projects Team on Vercel.

A member of the Team first needs to authorize it.

@ahmetalkan

Copy link
Copy Markdown

Thanks for this fix — the inert approach is solid and keeps the open/close transitions untouched.

For the maintainers' consideration, there is a one-line CSS alternative that also fully fixes #777: adding visibility: hidden to .float-panel-closed removes the whole subtree from the tab order and the accessibility tree, since visibility: hidden is inherited and disables focusability.

.float-panel-closed {
    @apply -translate-y-1 opacity-0 pointer-events-none;
    visibility: hidden;
}

Two caveats vs. this PR:

  • Panels using Tailwind's default transition class (e.g. #light-dark-panel) do not transition visibility by default, so the close animation would snap unless visibility is added to transition-property (panels using transition-all are unaffected).
  • inert additionally blocks assistive-tech traversal and hit testing explicitly, which some may prefer semantically.

Verified against main (6d39b0d) with keyboard walks at 1280×720 and 390×844: with the CSS change, invisible focus stops drop from 9 (desktop) / 7 (mobile) to 0, and all four panels still open, close and re-close correctly. Either approach works; sharing the measurement in case it helps the decision.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Controls inside closed floating panels remain in the Tab order / 关闭的浮动面板控件仍参与 Tab 顺序

2 participants